package com.micolor.logr.runtime.joinpoints;

import com.micolor.logr.runtime.annotation.LogComponent;
import com.micolor.logr.runtime.annotation.LogField;
import com.micolor.logr.runtime.component.EnumDataComponent;
import com.micolor.logr.runtime.entity.*;
import com.micolor.logr.runtime.enums.LogRConfigEnum;
import com.micolor.logr.runtime.properties.LogREnumsProperties;
import com.micolor.logr.runtime.util.ClazzAndMapUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author EvanGe
 * @Type InsertJoinPoint.java
 * @Desc
 * @date 2024/7/8 14:31
 */
@Component
@Slf4j
public class InsertJoinPoint {

    @Autowired
    EnumDataComponent enumDataComponent;
    @Resource
    private LogREnumsProperties logREnumsProperties;
    public StorageData joinPoint(StorageData storageData,LogMessage logMessage, LogComponent logComponent, List<FieldDetail> logFields, Object resultObject)
            throws
            IllegalAccessException,
            ClassNotFoundException,
            InvocationTargetException,
            NoSuchMethodException{
        //将result从Object类型转换成Map类型
        Map<String,Object> resultMap = ClazzAndMapUtil.transObjectToMap(resultObject,logComponent.callSuper());

        StringBuilder message = new StringBuilder();
        StringBuilder targets = new StringBuilder();
        Map<String,Object> shardingMap = new HashMap<>();
        for(FieldDetail field : logFields){
            LogField logField = field.getLogField();
            if(resultMap.get(field.getFieldName())!=null){
                LogMessageItem logMessageItem = new LogMessageItem();
                logMessageItem.setName(field.getFieldName());
                logMessageItem.setDesc(logField.value());
                logMessageItem.setOriginalValue(resultMap.get(field.getFieldName()));
                logMessageItem.setTransValue(resultMap.get(field.getFieldName()));

                //开始处理各种注解设定的东西

                //处理enumTrans的标志
                if(!logField.enumTrans().isEmpty()){
                    String enumTrans = logField.enumTrans();
                    List<LogFieldEnum> logFieldEnums;
                    if(!logField.enumPrecision()){
                        String enumName = enumTrans.split(":")[0];
                        String enumType = enumTrans.split(":")[1];
                        logFieldEnums = enumDataComponent.getEnumObject(enumName,enumType);
                    }else{
                        logFieldEnums = enumDataComponent.getEnumObject(enumTrans,resultMap);
                    }
                    if(!logFieldEnums.isEmpty()){
                        logFieldEnums.stream().filter(e -> e.getKey().equals(logMessageItem.getOriginalValue())).
                                findFirst().ifPresent(logFieldEnum ->
                                        logMessageItem.setTransValue(logFieldEnum.getValue()+"["+logMessageItem.getOriginalValue()+"]"));
                    }
                }

                //处理日期
                if(!logField.dateFormat().isEmpty()){
                    String regx = logField.dateFormat();
                    Date date = (Date)resultMap.get(field.getFieldName());
                    String dateStr = new SimpleDateFormat(regx).format(date);
                    logMessageItem.setTransValue(dateStr);
                    //新增操作特殊处理
                    //将时间放入到logMessage中
                    logMessage.setTime(dateStr);
                    storageData.setOperateTime(date);
                }

                //处理操作人
                if(logField.isCreateOperator()){
                    logMessage.setOperator(String.valueOf(resultMap.get(field.getFieldName())));
                    storageData.setOperatorName(logMessage.getOperator());
                }

                //是否是业务主键
                if(logField.isBizId()){
                    storageData.setBizId(String.valueOf(resultMap.get(field.getFieldName())));
                }
                //是否是关联对象
                if(logField.isTarget()){
                    targets.append(resultMap.get(field.getFieldName())).append(",");
                }
                //设置操作人
                if(field.getFieldName().equals("createBy")){
                    storageData.setOperator(String.valueOf(resultMap.get(field.getFieldName())));
                }

                //处理分表字段
                if(logField.isShardingField()){
                    shardingMap.put(field.getFieldName(),resultMap.get(field.getFieldName()));
                }
                message.append(logMessageItem.getDesc()).append(":").append(logMessageItem.getTransValue()).append(",");
            }
        }
        if(!targets.isEmpty()){
            storageData.setTargets(targets.substring(0,targets.length()-1));
        }
        storageData.setShardingInfo(shardingMap);
        //判断最后记录日志是按何种方式记录的，simple为简单，detail为详细
        //当为simple时，不记录详细信息
        log.warn(logREnumsProperties.getStrategy());
        log.warn(LogRConfigEnum.LogR_Strategy_Detail.toString());


        if(logREnumsProperties.getStrategy().equals(LogRConfigEnum.LogR_Strategy_Detail.toString())){
            logMessage.setDetail(message.substring(0,message.length()-1));
        }else{
            logMessage.setDetail("简单记录模式不记录具体信息");
        }
        storageData.setShardingInfo(shardingMap);
        storageData.setMessage(logMessage);
        return storageData;
    }
}
